package fr.afcepf.atod18.fw.controler;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.parsers.ParserConfigurationException;

import org.xml.sax.SAXException;

import fr.afcepf.atod18.fw.action.ActionConnexion;
import fr.afcepf.atod18.fw.action.ActionIndex;
import fr.afcepf.atod18.fw.action.ActionInscription;
import fr.afcepf.atod18.fw.action.ActionLogout;
import fr.afcepf.atod18.fw.action.IAction;
import fr.afcepf.atod18.fw.entities.Action;
import fr.afcepf.atod18.fw.entities.Form;
import fr.afcepf.atod18.fw.form.ConnexionForm;
import fr.afcepf.atod18.fw.form.IActionForm;
import fr.afcepf.atod18.fw.form.IndexForm;
import fr.afcepf.atod18.fw.form.InscriptionForm;
import fr.afcepf.atod18.fw.form.LogoutForm;
import fr.afcepf.atod18.fw.parser.ParserXml;


/**
 * Servlet implementation class ServletDispatch
 * Cette servlet constitue le contôleur
 */
public class ActionServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;
    
    private Map<String, Class> mapAction  = new HashMap<String, Class>();
    private Map<String, Class> mapActionForm  = new HashMap<String, Class>();
    
    
    Factory factory;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public ActionServlet() {
        super();
        
       
        // TODO Auto-generated constructor stub
    }
    
    
    public void init(ServletConfig config) throws ServletException {
        
        super.init(config);
		List<Map<String, Object>> listeMapsParsees = null;
		String nomFicRessources = getServletContext().getInitParameter("nomFicParam"); 
		ParserXml parserXml = new ParserXml();
		
		Action a = new Action();
		Form f = new Form();

		nomFicRessources = Thread.currentThread().getContextClassLoader().getResource("../.."+nomFicRessources).getPath();
		
		List<Object> lTags = new ArrayList<Object>();
		lTags.add(a);
		lTags.add(f);
		
		try {
			listeMapsParsees = parserXml.parse(nomFicRessources, lTags);
			System.out.println("listeMapsParsees de taille "+ listeMapsParsees.size());
		} catch (ParserConfigurationException | SAXException | IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		for (int i =0; i<listeMapsParsees.size(); i++ ){
			Map<String, Object> map = listeMapsParsees.get(i);
			
			Collection<Object> coll = map.values();
			List<Object> tempList = new ArrayList<Object>(coll);
			
			for (int j = 0; j < tempList.size(); j++){
				Object o = tempList.get(j);
				System.out.println(o.toString());
				if ( o.getClass().getSimpleName().equals("Action")) {
					/* on remplit la mapAction*/
					Action action = (Action) o;
			        try {
						mapAction.put(action.getUrl_pattern(), Class.forName (action.getForm_name()));
					} catch (ClassNotFoundException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
				if (o.getClass().getSimpleName().equals("Form")){
					/* on remplit la mapActionForm*/
					Form form = (Form) o;
					try {
						mapActionForm.put(form.getForm_name(), Class.forName (form.getForm_class()));
					} catch (ClassNotFoundException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			}
			System.out.println(mapAction.size()+ " actions dans mapAction");
			System.out.println(mapActionForm.size()+ " forms dans mapActionForm");
			
		}
        
//        //Map temporaire juste pour les tests
//        mapAction.put("/index.html", ActionIndex.class);
//        mapAction.put("/logoutAction.perform", ActionLogout.class);
//        mapAction.put("/inscriptionAction.perform", ActionInscription.class);
//        mapAction.put("/connexionAction.perform", ActionConnexion.class);
//        
//        mapActionForm.put("/index.html", IndexForm.class);
//        mapActionForm.put("/logoutAction.perform", LogoutForm.class);
//        mapActionForm.put("/inscriptionAction.perform", InscriptionForm.class);
//        mapActionForm.put("/connexionAction.perform", ConnexionForm.class);
        
        factory  = new Factory();
    }

    /**
     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        
        String suite;
        
        String provenance = request.getServletPath();
        
        // affichage des saisies de la form
        System.out.println("ServletPath=" + request.getServletPath());
        Map<String, String[]> mapParam = request.getParameterMap();
        System.out.println("taille mapParam=" + mapParam.size());
        Set<String> listeKey = mapParam.keySet();
        String ligneSaisie = "";
        for(String key : listeKey) {
            String[] saisie = mapParam.get(key);
            for(int i = 0; i < saisie.length; i++) {
                ligneSaisie += saisie[i];
            }
            System.out.println(key + "=" + ligneSaisie);
        }
        
        Class<IActionForm> formClass = mapActionForm.get(request.getServletPath());
        System.out.println("form=" + formClass);
        
        IActionForm formAction = null;
        try {
            formAction = (IActionForm) formClass.newInstance();
        } catch (InstantiationException | IllegalAccessException e) {
            // TODO Bloc catch généré automatiquement
            e.printStackTrace();
        }
        MyBeanPopulate.populateBean(formAction, mapParam);
        
        System.out.println("populated form=" + formAction);

        IAction a = factory.done(provenance, mapAction );
        
        // Execution action
        //TODO: attention au validateForm à true/false!
        if (!formAction.validateForm())
            suite = a.execute(request, response);
        else
            suite="/pages/error.jsp";
            
        
        request.getRequestDispatcher(suite).forward(request, response);
    }

    /**
     * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet( request, response);
    }
 
}
